package com.grantheath.erebus.view 
{
	import com.grantheath.erebus.model.interfaces.IErebusPreferencesProxy;
	import com.grantheath.erebus.model.enum.notifications.ErebusPreloaderNotifications;
	import com.grantheath.erebus.model.enum.notifications.ErebusPageLoaderNotifications;
	import com.grantheath.erebus.model.enum.notifications.ErebusAssetLoaderNotifications;
	import com.grantheath.erebus.model.enum.names.ErebusMediatorNames;
	import com.grantheath.erebus.model.enum.names.ErebusProxyNames;
	import com.grantheath.erebus.model.interfaces.IErebusAssetNode;
	import com.grantheath.erebus.model.interfaces.IErebusPageNode;
	import com.grantheath.erebus.view.helpers.ErebusPageEvent;
	import com.grantheath.erebus.view.helpers.ErebusTimer;
	import com.grantheath.erebus.view.interfaces.IErebusPagePreloader;

	import org.puremvc.as3.interfaces.INotification;
	import org.puremvc.as3.interfaces.IMediator;
	import org.puremvc.as3.patterns.mediator.Mediator;
	
	import flash.events.TimerEvent;

	/**
	 * @author grantheath
	 */
	public class ErebusPagePreloaderMediator extends Mediator implements IMediator 
	{
		public function ErebusPagePreloaderMediator()
		{
			super(ErebusMediatorNames.PAGE_PRELAODER_MEDIATOR);
		}

		override public function listNotificationInterests() : Array
		{
			return[ErebusPreloaderNotifications.SHOW_PRELOADER,
				ErebusPreloaderNotifications.HIDE_PRELOADER,
				ErebusPreloaderNotifications.CLEAR_PRELOADER_TRANSITION_EVENTS,
				ErebusPageLoaderNotifications.PAGE_LOAD_OPEN,
				ErebusPageLoaderNotifications.PAGE_LOAD_ERROR,
				ErebusPageLoaderNotifications.PAGE_LOAD_PROGRESS,
				ErebusPageLoaderNotifications.PAGE_LOAD_COMPLETE,
				ErebusAssetLoaderNotifications.ASSET_LOAD_OPEN,
				ErebusAssetLoaderNotifications.ASSET_LOAD_ERROR,
				ErebusAssetLoaderNotifications.ASSET_LOAD_PROGRESS,
				ErebusAssetLoaderNotifications.ASSET_LOAD_COMPLETE];
		}

		override public function handleNotification(notification : INotification) : void
		{
			var notificationName : String = notification.getName();
			var pageNode : IErebusPageNode = notification.getBody() as IErebusPageNode;
			var preferences : IErebusPreferencesProxy = facade.retrieveProxy(ErebusProxyNames.PREFERENCES_PROXY) as IErebusPreferencesProxy;
			
			if(pageNode) {
				if(notificationName == ErebusPreloaderNotifications.SHOW_PRELOADER) {
					if(pageNode.isLoaded) {
						facade.sendNotification(ErebusPreloaderNotifications.PRELOADER_HIDDEN, pageNode);
					} else {
						var timer : ErebusTimer = new ErebusTimer(preferences.preloaderDelay, pageNode);
						
						timer.addEventListener(TimerEvent.TIMER_COMPLETE, onTimerComplete);
						timer.start();
					}
				} else if(pageNode.pagePreloader) {
					if(notificationName == ErebusPreloaderNotifications.HIDE_PRELOADER) {
						pageNode.pagePreloader.transitionHandeler.addEventListener(ErebusPageEvent.TRANSITION_OUT_COMPLETE, onTransitionOutComplete);
						if(pageNode.pagePreloader.isTransitioning){
							pageNode.pagePreloader.transitionInterupted = true;
						} else {
							pageNode.pagePreloader.isTransitioning = true;
							pageNode.pagePreloader.transitionHandeler.transitionOut();
						}
					} else if(notificationName == ErebusPageLoaderNotifications.PAGE_LOAD_PROGRESS) {
						pageNode.pagePreloader.onPageProgress(pageNode);
					} else if(notificationName == ErebusPageLoaderNotifications.PAGE_LOAD_OPEN) {
						pageNode.pagePreloader.onPageOpen(pageNode);
					} else if(notificationName == ErebusPageLoaderNotifications.PAGE_LOAD_ERROR) {
						pageNode.pagePreloader.onPageError(pageNode);
					} else if(notificationName == ErebusPageLoaderNotifications.PAGE_LOAD_COMPLETE) {
						pageNode.pagePreloader.onPageComplete(pageNode);
					}
				}
			} else {
				var assetNode : IErebusAssetNode = notification.getBody() as IErebusAssetNode;
				
				if(assetNode.pageNode.pagePreloader) {
					if(notificationName == ErebusAssetLoaderNotifications.ASSET_LOAD_PROGRESS) {
						assetNode.pageNode.pagePreloader.onAssetProgress(assetNode);
					} else if(notificationName == ErebusAssetLoaderNotifications.ASSET_LOAD_OPEN) {
						assetNode.pageNode.pagePreloader.onAssetOpen(assetNode);
					} else if(notificationName == ErebusAssetLoaderNotifications.ASSET_LOAD_ERROR) {
						pageNode.pagePreloader.onPageError(pageNode);
					} else if(notificationName == ErebusAssetLoaderNotifications.ASSET_LOAD_COMPLETE) {
						assetNode.pageNode.pagePreloader.onAssetComplete(assetNode);
					} else if(notificationName == ErebusPreloaderNotifications.CLEAR_PRELOADER_TRANSITION_EVENTS) {
						trace("clearing preloader tansition events for node: " + pageNode);
						clearPreloaderTransitionEvents(pageNode);
					}
				}
			}
		}

		private function clearPreloaderTransitionEvents(pageNode : IErebusPageNode) : void
		{
			if(pageNode.pagePreloader) {
				pageNode.pagePreloader.transitionHandeler.removeEventListener(ErebusPageEvent.TRANSITION_IN_COMPLETE, onTransitionInComplete);
				pageNode.pagePreloader.transitionHandeler.removeEventListener(ErebusPageEvent.TRANSITION_OUT_COMPLETE, onTransitionOutComplete);
			}
		}

		//EVENT HANDELERS		
		private function onTransitionInComplete(event : ErebusPageEvent) : void
		{
			var preLoader : IErebusPagePreloader = event.target.target as IErebusPagePreloader;
			
			preLoader.isTransitioning = false;
			if(preLoader.transitionInterupted) {
				preLoader.transitionInterupted = false;
				preLoader.transitionHandeler.transitionOut();
			}
			facade.sendNotification(ErebusPreloaderNotifications.PRELOADER_SHOWN, event);
		}

		private function onTransitionOutComplete(event : ErebusPageEvent) : void
		{
			var preLoader : IErebusPagePreloader = event.target.target as IErebusPagePreloader;
			
			preLoader.isTransitioning = false;
			if(preLoader.transitionInterupted) {
				preLoader.transitionInterupted = false;
				preLoader.transitionHandeler.transitionIn();
			}
			facade.sendNotification(ErebusPreloaderNotifications.PRELOADER_HIDDEN, preLoader.pageNode);
		}

		private function onLoadComplete(event : ErebusPageEvent) : void
		{
			var preLoader : IErebusPagePreloader = event.target as IErebusPagePreloader;
			
			sendNotification(ErebusPreloaderNotifications.HIDE_PRELOADER, preLoader.pageNode);
		}

		private function onTimerComplete(event : TimerEvent) : void
		{
			var timer : ErebusTimer = event.target as ErebusTimer;
			var pageNode : IErebusPageNode = timer.pageNode;
			
			if(pageNode.isLoaded) {
				facade.sendNotification(ErebusPreloaderNotifications.PRELOADER_HIDDEN, pageNode);
			} else {
				var preloaderClass : Class = pageNode.pagePreloaderClass;
				
				if(!pageNode.pagePreloader) {
					pageNode.pagePreloader = new preloaderClass();
					pageNode.pagePreloader.initializePreloader(pageNode);
					pageNode.pagePreloader.transitionHandeler.addEventListener(ErebusPageEvent.TRANSITION_IN_COMPLETE, onTransitionInComplete);
					pageNode.pagePreloader.addEventListener(ErebusPageEvent.PRELOADER_LOAD_COMPLETE, onLoadComplete);
				}
				if(pageNode.pagePreloader.isTransitioning) {
					pageNode.pagePreloader.transitionInterupted = true;
				} else {
					pageNode.pagePreloader.isTransitioning = true;
					pageNode.pagePreloader.transitionHandeler.transitionIn();
				}
			}
		}
	}
}